package com.alibaba.citrus.cr.mn.order.center.facade.function.common;

import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.mn.order.center.facade.function.check.AbstractOrderParamsCheckService;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.AbstractOrderParamsConvertService;
import com.alibaba.citrus.cr.mn.order.center.facade.function.dataobject.AtomOrderDO;
import com.alibaba.cz.base.tool.log.Log;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author zhangxiaorui
 * @ClassName OrderAtomCreateService2
 * @description: TODO
 * @date 2023/05/17 11:33
 * @version: 1.0
 */
public interface OrderAtomCreateService<AtomInput, AtomOutput> {

    Log log = Log.getLogger(OrderAtomCreateService.class);

    /**
     * 销售订单创建订单核心处理逻辑（原子能力）【单条】
     *
     * @param request
     * @return
     */
    default AtomOutput create(AtomInput request) {
        ArrayList<AtomInput> requests = Lists.newArrayList(request);
        List<AtomOutput> responseList = batchCreate(requests);
        return CollectionUtils.isEmpty(responseList) ? null : responseList.get(0);
    }

    /**
     * 销售订单创建订单核心处理逻辑（原子能力）【批量】
     *
     * @param requestList
     * @return
     */
    default List<AtomOutput> batchCreate(List<AtomInput> requestList) {
        try {
            List<AtomOutput> responseList = Collections.synchronizedList(new ArrayList<>());

            // 1.0 参数合法性校验
            paramsInvalidCheck(requestList, responseList);

            // 2.0 原子DTO->领域对象转换
            List<AtomOrderDO> orderWriteList = convert(requestList);

            // 2.5 防御编程-创单重复校验【来源单号幂等校验
            idempotentProcess(orderWriteList, responseList);

            // 3.0 原子能力业务校验
            bizCheck(orderWriteList);

            // 4.0 数据库事务提交
            submitSaveTransactional(orderWriteList, responseList);

            // 5.0 后置处理：SAP创单消息发送+其他业务处理 (目前放置在上层处理，可以考虑事件驱动实现
            afterSubmitTransactional(orderWriteList);

            // 5.5 打印链路耗时日志
            printExecConsumerTime();

            // 6.0 构造返回数据
            return responseList;
        } catch (FunctionException ex) {
            log.error("OrderAtomCreateService#batchCreate funcError", ex);
            throw ex;
        } catch (Exception e) {
            log.error("OrderAtomCreateService#batchCreate error", e);
            throw e;
        }
    }

    default void paramsInvalidCheck(List<AtomInput> requestList, List<AtomOutput> responseList) {
        if (getCheckService() != null) {
            getCheckService().paramsInvalidCheck(requestList, responseList);
        }
    }

    void idempotentProcess(List<AtomOrderDO> orderWriteList, List<AtomOutput> responseList);

    default List<AtomOrderDO> convert(List<AtomInput> requestList) {
        if (getCheckService() != null) {
            return getConvertService().convert(requestList);
        }
        return Lists.newArrayList();
    }

    default void bizCheck(List<AtomOrderDO> orderWriteList) {
        // 默认不实现业务校验
    }

    void submitSaveTransactional(List<AtomOrderDO> orderWriteList, List<AtomOutput> responseList);

    default void afterSubmitTransactional(List<AtomOrderDO> orderWriteList) {
        // 默认不实现后置处理
    }

    default void printExecConsumerTime() {
        throw new RuntimeException("此方法未被实现");
    }

    AbstractOrderParamsCheckService<AtomInput, AtomOutput> getCheckService();

    AbstractOrderParamsConvertService<AtomInput, AtomOrderDO> getConvertService();
}